import { h, watch } from 'vue';
import { IPSAppView } from '@ibiz/dynamic-model-api';
import { IParam } from 'ibz-core';
import { GetModelService, Util } from 'ibz-core';
import { ComponentBase, GenerateComponent } from 'ibz-ui-ionic';

export class AppRouteShell extends ComponentBase {

  /**
   * @description 动态模型文件路径
   * @type {string}
   * @memberof AppRouteShell
   */
  public dynaModelFilePath: string = '';

  /**
   * @description 视图容器
   * @type {*}
   * @memberof AppRouteShell
   */
  public viewComponent: any;

  /**
   * 计算视图动态路径
   *
   * @memberof AppRouteShell
   */
  init() {
    this.computeDynaModelFilePath(this.route);
    this.router.beforeEach(async (to, from) => {
      // TODO 实体视图默认都是登录用户访问，测试环境不能登录导致实体视图都无法跳转，先注释
      // return await this.accessUserAuth(to);
      return true;
    });
  }

  /**
   * @description 构建组件
   * @memberof AppRouteShell
   */
  setup(): void {
    if (!this.route?.meta?.dynaModelFilePath) {
      watch(() => this.route.fullPath, () => {
        this.computeDynaModelFilePath(this.route);
      })
    }
  }

  /**
   * @description 访问用户验证
   * @param {*} route 路由
   * @memberof AppRouteShell
   */
  public async accessUserAuth(route: any) {
    const dynaModelFilePath = await this.getDynaModelFilePath(route);
    const viewModel = await ((await GetModelService()).getPSAppView(dynaModelFilePath)) as IPSAppView;
    return await App.getAppAuthService().getUserAccessAuth(viewModel);
  }

  /**
   * @description 计算视图动态路径
   * @param {*} route 路由
   * @memberof AppRouteShell
   */
  public async computeDynaModelFilePath(route: any) {
    this.dynaModelFilePath = await this.getDynaModelFilePath(route);;
    await this.loadDynamicModelData();
  }

  /**
   * @description 获取模型动态路径
   * @param {*} route 路由
   * @memberof AppRouteShell
   */
  public async getDynaModelFilePath(route: any): Promise<string> {
    let dynaModelFilePath = '';
    if (route && route.meta) {
      if (route.meta.dynaModelFilePath) {
        dynaModelFilePath = this.route.meta.dynaModelFilePath as string;
      } else {
        if (route.meta.parameters) {
          let resource: string = route.meta.resource ? (route.meta.resource as string).toLowerCase() : '';
          let activedView: IParam | undefined = (route.meta.parameters as Array<IParam>).find((item: IParam) => {
            return item.pathName === 'views';
          });
          let localActivedView: IParam = Util.deepCopy(activedView);
          if (Object.is(localActivedView.parameterName, 'view') && Object.is(localActivedView.pathName, 'views')) {
            localActivedView.parameterName = this.parseUrlDynamicParam(route).view;
          }
          if (localActivedView && localActivedView.parameterName) {
            const path = (await GetModelService()).getPSAppViewPath(`${resource}${localActivedView.parameterName}`);
            if (path) {
              dynaModelFilePath = path;
            }
          }
        }
      }
    }
    return dynaModelFilePath;
  }

  /**
   * @description 加载动态模型数据
   * @return {*} 
   * @memberof AppRouteShell
   */
  public async loadDynamicModelData() {
    const modeldata = await ((await GetModelService()).getPSAppView(this.dynaModelFilePath)) as IPSAppView;
    //  未找到模型数据跳转404页面
    if (Util.isEmpty(modeldata)) {
      this.router.push('/404');
      return;
    } else {
      this.viewComponent = App.getComponentService().getViewTypeComponent(
        (modeldata as IPSAppView).viewType,
        (modeldata as IPSAppView).viewStyle,
        (modeldata as IPSAppView)?.getPSSysPFPlugin()?.pluginCode
      );
      this.forceUpdate();
    }
  }

  /**
   * @description 解析路由动态参数
   * @param {*} route 路由
   * @return {*}  {*}
   * @memberof AppRouteShell
   */
  public parseUrlDynamicParam(route: any): any {
    const path = (route.matched[route.matched.length - 1]).path;
    const keys: Array<any> = [];
    const curReg = this.pathToRegExp.pathToRegexp(path, keys);
    const matchArray = curReg.exec(route.path);
    let tempValue: Object = {};
    keys.forEach((item: any, index: number) => {
      if (matchArray[index + 1]) {
        Object.defineProperty(tempValue, item.name, {
          enumerable: true,
          value: decodeURIComponent(matchArray[index + 1])
        });
      }
    });
    return tempValue;
  }

  /**
   * @description 绘制内容
   * @return {*} 
   * @memberof AppRouteShell
   */
  render() {
    if (this.viewComponent) {
      return h(this.viewComponent, {
        viewPath: this.dynaModelFilePath
      });
    } else {
      return null;
    }
  }
}
export const AppRouteShellComponent = GenerateComponent(AppRouteShell);